package com.ruoyi.business.controller;

import cn.hutool.core.comparator.CompareUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.business.domain.TRegisterDept;
import com.ruoyi.business.domain.TRegisterInfo;
import com.ruoyi.business.domain.TRegisterNeed;
import com.ruoyi.business.domain.TUserOptLog;
import com.ruoyi.business.enums.AuditStatusEnums;
import com.ruoyi.business.enums.GraduationAuditStatusEnums;
import com.ruoyi.business.enums.NoticeStatusEnums;
import com.ruoyi.business.service.*;
import com.ruoyi.business.utils.ZipFileUtils;
import com.ruoyi.business.vo.TAuditLogVo;
import com.ruoyi.business.vo.TRegisterInfoVo;
import com.ruoyi.business.vo.TRegisterNoticeVo;
import com.ruoyi.business.vo.TRegisterXXQYVo;
import com.ruoyi.business.vo.export.ExportRegisterInfoNoMoneyVo;
import com.ruoyi.business.vo.export.ExportRegisterInfoVo;
import com.ruoyi.business.vo.export.ExportSignedFilesVo;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.RoleConstants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 报名信息Controller
 *
 * @author Tellsea
 * @date 2024-01-24
 */
@Api(tags = "报名信息Controller")
@RestController
@RequestMapping("/business/registerInfo")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class TRegisterInfoController extends BaseController {

    private final ITRegisterInfoService tRegisterInfoService;
    private final SmsService smsService;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private ITRegisterNeedService registerNeedService;
    @Autowired
    private SysUserMapper userMapper;
    private final ITUserOptLogService tUserOptLogService;
    @Autowired
    private PlatformTransactionManager transactionManager;
    @Autowired
    private ITRegisterNoticeService registerNoticeService;
    @Autowired
    private ITRegisterBaseService registerBaseService;
    @Autowired
    private ITRegisterDeptService registerDeptService;
    @Autowired
    private ITAuditLogService auditLogService;
    @Autowired
    private Environment env;

    @ApiOperation("查询报名信息列表")
    @PreAuthorize("@ss.hasPermi('business:registerInfo:list')")
    @GetMapping("/list")
    public TableDataInfo<TRegisterInfoVo> list(TRegisterInfoVo entity) {
        entity.setUserId(SecurityUtils.getLoginUser().getUserId());
        return tRegisterInfoService.queryList(entity);
    }

    @ApiOperation("查询报名信息列表")
    @GetMapping("/queryListByStudent")
    public TableDataInfo<TRegisterInfoVo> queryListByStudent(TRegisterInfoVo entity) {
        if(entity.getGraduationStatusList()==null || entity.getGraduationStatusList().isEmpty()){
            entity.setGraduationStatusList(Arrays.asList(1L,2L,3L,4L));
        }
        return tRegisterInfoService.queryListByStudent(entity);
    }

    @ApiOperation("查询报名信息列表")
    @PreAuthorize("@ss.hasPermi('business:registerInfo:list')")
    @GetMapping("/index/list")
    public TableDataInfo<TRegisterInfoVo> indexList(TRegisterInfoVo entity) {
        Long userId = SecurityUtils.getLoginUser().getUserId();
        entity.setUserId(userId);
        entity.setAgentUserId(userId);
        return tRegisterInfoService.queryIndexList(entity);
    }


    @ApiOperation("查询报名信息所有列表")
    @GetMapping("/listAll")
    public AjaxResult listAll(TRegisterInfoVo entity) {
        return AjaxResult.success("查询成功", tRegisterInfoService.queryAll(entity));
    }

    @ApiOperation("导出报名信息列表")
    @PreAuthorize("@ss.hasPermi('business:registerInfo:export')")
    @Log(title = "报名信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, TRegisterInfoVo entity) {
        entity.setUserId(SecurityUtils.getLoginUser().getUserId());
        List<ExportRegisterInfoVo> list = tRegisterInfoService.getExportList(entity);
        boolean isSystem = SecurityUtils.hasRole(RoleConstants.SYSTEM.getRoleKey());
        boolean isAdmin = SecurityUtils.hasRole(RoleConstants.ADMIN.getRoleKey());
        if (isSystem || isAdmin) {
            ExcelUtil<ExportRegisterInfoVo> util = new ExcelUtil<>(ExportRegisterInfoVo.class);
            util.exportExcel(response, list, "报名信息数据");
            return;
        }
        ExcelUtil<ExportRegisterInfoNoMoneyVo> util = new ExcelUtil<>(ExportRegisterInfoNoMoneyVo.class);
        List<ExportRegisterInfoNoMoneyVo> newList = new ArrayList<>();
        for (ExportRegisterInfoVo exportRegisterInfoVo : list) {
            ExportRegisterInfoNoMoneyVo vo = new ExportRegisterInfoNoMoneyVo();
            BeanUtils.copyBeanProp(vo,exportRegisterInfoVo);
            newList.add(vo);
        }
        util.exportExcel(response, newList, "报名信息数据");
    }

    @ApiOperation("导出已签字文件列表")
    @PreAuthorize("@ss.hasPermi('business:registerInfo:export')")
    @Log(title = "导出已签字文件列表", businessType = BusinessType.EXPORT)
    @PostMapping("/exportSignFile")
    public void exportSignFile(HttpServletResponse response, TRegisterInfoVo entity) {
        entity.setUserId(SecurityUtils.getLoginUser().getUserId());
        String projectPath = System.getProperty("user.dir") + "/uploadPath";
        String zipTmpPath = projectPath+"/tmp";
        if(!FileUtil.isDirectory(zipTmpPath)){
            FileUtil.mkdir(zipTmpPath);
        }
        List<File> cacheFiles = new ArrayList<>();
        List<ExportSignedFilesVo> list = tRegisterInfoService.exportAllSignedFiles(entity);
        for (ExportSignedFilesVo filesVo : list) {
            String signPdfFile = filesVo.getSignPdfFile();
            String oriFilePaths = signPdfFile.replace("/profile", "");
            String oriFileName = FileUtil.mainName(oriFilePaths);
            String[] fileNameArr = oriFileName.split("-");
            String targetName = oriFileName+".pdf";
            if(fileNameArr.length==3){
                targetName = fileNameArr[1]+"-"+fileNameArr[2]+"-"+fileNameArr[0]+".pdf";
            }
            File sourceFile = FileUtil.file(projectPath + oriFilePaths);
            File targetFile = FileUtil.file(zipTmpPath+"/" + targetName);
            FileUtil.copyFile(sourceFile,targetFile);
            cacheFiles.add(targetFile);
        }
        // 压缩
        String dateFormat = DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_PATTERN);
        String dateFolder = DateUtil.format(DateUtil.date(), "yyyy/MM/dd/");
        File targetZipFile = FileUtil.file(projectPath + "/upload/" + dateFolder + "已签字名单-" + dateFormat + ".zip");
        // 文件压缩成zip
        ZipFileUtils.generateZip(targetZipFile, cacheFiles, false);
        ZipFileUtils.downloadZip(targetZipFile,response);
        for (File file : cacheFiles) {
            FileUtil.del(file);
        }
    }

    @ApiOperation("获取报名信息详细信息")
    @PreAuthorize("@ss.hasPermi('business:registerInfo:query')")
    @GetMapping(value = "/getInfo/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        TRegisterInfoVo tRegisterInfoVo = tRegisterInfoService.queryById(id);
        List<TAuditLogVo> list = auditLogService.listByRegistId(id);
        tRegisterInfoVo.setAuditLogVoList(list);
        return AjaxResult.success("查询成功", tRegisterInfoVo);
    }

    @ApiOperation("获取学员报名流程状态")
    @PreAuthorize("@ss.hasPermi('business:registerInfo:query')")
    @GetMapping(value = "/getFlow/{id}")
    public AjaxResult getFlow(@PathVariable("id") Long id) {
        return AjaxResult.success("查询成功", tRegisterInfoService.getFlow(id));
    }

    @ApiOperation("新增报名信息-之前")
    //@PreAuthorize("@ss.hasPermi('business:registerInfo:add')")
    @Log(title = "报名信息", businessType = BusinessType.INSERT)
    @PostMapping("addBefore")
    public AjaxResult addBefore(@RequestBody TRegisterInfoVo entity) {
        entity.setUserId(SecurityUtils.getLoginUser().getUserId());
        return tRegisterInfoService.saveBefore(entity);
    }

    @ApiOperation("新增报名信息")
    //@PreAuthorize("@ss.hasPermi('business:registerInfo:add')")
    @Log(title = "报名信息", businessType = BusinessType.INSERT)
    @PostMapping("add")
    public AjaxResult add(@RequestBody TRegisterInfoVo entity) {
        entity.setUserId(SecurityUtils.getLoginUser().getUserId());
        return tRegisterInfoService.saveEntity(entity);
    }

    @ApiOperation("代理报名")
    @Log(title = "报名信息", businessType = BusinessType.INSERT)
    @PostMapping("agent")
    public AjaxResult agent(@RequestBody TRegisterInfoVo entity) {
        TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
        try {
            SysUser user = new SysUser();
            if (StringUtils.isNotEmpty(entity.getPhoneNumber())
                    && UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(entity.getPhoneNumber()))) {
                user = userMapper.checkPhoneUnique(entity.getPhoneNumber());
            }else {
                //如果用户未注册过，则进行系统自动注册,并设置角色为5（学员）
                user.setCreateBy(getUsername());
                user.setPhonenumber(entity.getPhoneNumber());
                user.setNickName(entity.getApplicantName());
                user.setUserName(entity.getPhoneNumber());
                user.setRegisterDeptId(entity.getRegisterDeptId());
                user.setPassword(SecurityUtils.encryptPassword("123456"));
                user.setCreateTime(new Date());
                Long [] aLong = {5L};
                user.setRoleIds(aLong);
                userService.insertUser(user);
            }
            entity.setAuditStatus(AuditStatusEnums.SAVE.getCode());
            entity.setUserId(user.getUserId());
            entity.setAgentUserId(SecurityUtils.getLoginUser().getUserId());
            entity.setUserName(entity.getApplicantName());
            //获取招生信息ID
            QueryWrapper<TRegisterNeed> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("register_dept_id",entity.getRegisterDeptId());
            queryWrapper.orderByDesc("create_time").last("limit 1");
            TRegisterNeed tRegisterNeed = registerNeedService.getOne(queryWrapper);
            entity.setRegisterNeedId(tRegisterNeed.getId());
            //保存报名信息
            boolean save = tRegisterInfoService.save(entity);
            //发送短信通知
            String urlAddress = env.getProperty("web.url-address");
            smsService.sendMessage(entity.getPhoneNumber(), "学员" + entity.getApplicantName() + "您好，您的进修代理报名已生效，请使用电脑登录系统（"+urlAddress+"/engage-index/）学员端-我的申请-暂存按钮 完善信息。（帐号："+user.getUserName()+" 密码:123456）");
            SysUser loginUser = SecurityUtils.getLoginUser().getUser();
            List<String> roleList = new ArrayList<>();
            if(loginUser.getRoles()!=null){
                for (SysRole role : loginUser.getRoles()) {
                    roleList.add(role.getRoleName());
                }
            }

            TUserOptLog tUserOptLog = new TUserOptLog()
                    .setOptDesc("代理报名")
                    .setOptTime(entity.getUpdateTime())
                    .setFromUserid(loginUser.getUserId().toString())
                    .setFromUsername(loginUser.getNickName())
                    .setFromRolename(StringUtils.join(roleList,","))
                    .setToUserid(entity.getPhoneNumber())
                    .setToUsername(entity.getUserName());
            tUserOptLogService.save(tUserOptLog);
            transactionManager.commit(status);
            return toAjax(save);
        } catch (RuntimeException e) {
            transactionManager.rollback(status);
            logger.error(e.getMessage());
            return toAjax(false);
        }
    }

    @ApiOperation("修改报名信息")
    //@PreAuthorize("@ss.hasPermi('business:registerInfo:edit')")
    @Log(title = "报名信息", businessType = BusinessType.UPDATE)
    @PostMapping("edit")
    public AjaxResult edit(@RequestBody TRegisterInfoVo entity) {
        if (CompareUtil.compare(entity.getSureFlag(), 1L) == 0) {
            smsService.sendMessage(entity.getPhoneNumber(), "欢迎您来华山医院进修，根据教育处进修生管理规定，所有进" +
                    "修学员在线下报到前，需要完成岗前培训相关课程学习，请登录进修管理系统，个人中心-岗前培训专栏处进行线上学习。" +
                    " 电脑端系统登录链接：https://jx.edu-huashan.com:18084/engage-web/business/resourceInfo/indexList");
        }
        TRegisterInfoVo registerInfo = tRegisterInfoService.queryById(entity.getId());
        if (entity.getRegisterDeptId() !=null && !registerInfo.getRegisterDeptId().equals(entity.getRegisterDeptId())){
            //修改报名基地
            TRegisterDept registerDept = registerDeptService.getById(entity.getRegisterDeptId());
            TRegisterNoticeVo tRegisterNoticeVo = registerNoticeService.queryByRegisterId(entity.getId());
            if(tRegisterNoticeVo!=null){
                String jobNumber = registerBaseService.createJobNumber(registerDept);
                tRegisterNoticeVo.setOldJobNumber(tRegisterNoticeVo.getJobNumber());
                tRegisterNoticeVo.setJobNumber(jobNumber);
                registerNoticeService.updateById(tRegisterNoticeVo);
            }
        }
        SysUser loginUser = SecurityUtils.getLoginUser().getUser();
        List<String> roleList = new ArrayList<>();
        if(loginUser.getRoles()!=null){
            for (SysRole role : loginUser.getRoles()) {
                roleList.add(role.getRoleName());
            }
        }
        String optDesc = "修改申请信息";
        if (CompareUtil.compare(entity.getNoticeStatus(), NoticeStatusEnums.SUCCESS.getCode()) == 0){
            optDesc = "已确认通知书";
        }
        if (CompareUtil.compare(entity.getNoticeStatus(), NoticeStatusEnums.CANCEL.getCode()) == 0){
            optDesc = "已取消通知书";
        }
        if (CompareUtil.compare(entity.getGraduationAuditStatus(), GraduationAuditStatusEnums.NO.getCode()) == 0){
            optDesc = "结业申请";
        }
        if(StringUtils.isNotEmpty(entity.getScoreLevel())){
            optDesc = "考评评级";
        }
        if(!StringUtils.equals(optDesc,"修改申请信息")){
            TUserOptLog tUserOptLog = new TUserOptLog()
                    .setOptDesc(optDesc)
                    .setOptTime(DateUtils.getNowDate())
                    .setFromUserid(loginUser.getUserId().toString())
                    .setFromUsername(loginUser.getNickName())
                    .setFromRolename(StringUtils.join(roleList,","))
                    .setToUserid(entity.getId().toString())
                    .setToUsername(entity.getUserName());
            tUserOptLogService.save(tUserOptLog);
        }
        return toAjax(tRegisterInfoService.updateById(entity));
    }


    @ApiOperation("删除报名信息")
    @PreAuthorize("@ss.hasPermi('business:registerInfo:remove')")
    @Log(title = "报名信息", businessType = BusinessType.DELETE)
	@GetMapping("/remove/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        Boolean result = tRegisterInfoService.batchRemoveByIds(Arrays.asList(ids));
        return toAjax(result ? 1 : 0);
    }

    @ApiOperation("查询最新报名成功记录")
    @GetMapping("/getLast")
    public AjaxResult getLast() {
        return tRegisterInfoService.getLast();
    }


    @ApiOperation("判断进行是否可以继续提交")
    @GetMapping("/judgeRegister/{id}")
    public AjaxResult judgeRegister(@PathVariable Long id) {
        return tRegisterInfoService.judgeRegister(id);
    }
}
